﻿using System;
using System.Linq;
using Gfw.Infrastructure.ExceptionImpl;
using Gfw.Infrastructure.User;
using Gfw.Models.Account;
using Gfw.Models.Admin;
using Gfw.Repository;
using Gfw.Infrastructure.Account;
using Gfw.Repositories.Admin;
using Gfw.Repositories.Account;

namespace Gfw.Infrastructure.Facilities
{
    /// <summary>
    /// 充值（转账），客服转用户
    /// <para>用户转用户见Transfer类</para>
    /// </summary>
    public class RechargeFacility : IFacility
    {
        #region private fields

        string _userID, _bankCardNo, _bankName, _bankUserName, _bankSerialNo, _handlerID;
        int _status;
        decimal _rechargeMoney;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="bankCardNo"></param>
        /// <param name="bankName"></param>
        /// <param name="bankSerialNo"></param>
        /// <param name="bankUserName"></param>
        /// <param name="handlerID"></param>
        /// <param name="rechargeMoney"></param>
        /// <param name="status"></param>
        /// <param name="userID"></param>
        public RechargeFacility(string userID, string bankCardNo, string bankName,
            string bankUserName, decimal rechargeMoney, string bankSerialNo,
            string handlerID, int status)
        {
            var userRep = new UsrUserRepository();
            var user = userRep.Get(userID);
            if (user == null)
                throw new GfwVerifyException("充值账户不存在！");

            if (rechargeMoney <= 0)
                throw new GfwVerifyException("充值的金额不正确！");

            this._userID = userID;
            this._bankCardNo = bankCardNo;
            this._bankName = bankName;
            this._bankUserName = bankUserName;
            this._rechargeMoney = rechargeMoney;
            this._bankSerialNo = bankSerialNo;
            this._handlerID = handlerID;
            this._status = status;
        }

        #endregion

        #region IFacility 成员

        /// <summary>
        /// 客户转会员
        /// </summary>
        /// <param name="unitOfWork"></param>
        public void Execute(UnitOfWork unitOfWork = null)
        {
            try
            {
                if (unitOfWork != null)
                    throw new GfwException("当前事务只能作为原子事务，不允许与其它操作公用数据库事务。");

                UnitOfWork work = unitOfWork ?? new UnitOfWork();
                
                ActUserAccountinformationRepository userAccountRep = new ActUserAccountinformationRepository(); // 修改：用户账户信息表
                ActUserBargain4emoneyRepository emoneyRep = new ActUserBargain4emoneyRepository(); // 修改：用户电子币交易明细
                /* Modify by: Fan 2012-08-08
                 * 由于并发的原因，公司账户在每晚进行结算。
                ActCompanyAccountinformationRepository comAccountRep = new ActCompanyAccountinformationRepository(); // 修改：公司帐户信息表
                 */
                ActCompanyRechargeRepository rechargeRep = new ActCompanyRechargeRepository(); // 修改：公司(用户)充值记录表
                ActCompanyBargainRepository bargainRep = new ActCompanyBargainRepository(); // 修改：公司帐户交易明细

                var userAccount = userAccountRep.Get(this._userID, work);
                if (userAccount == null)
                    throw new GfwVerifyException("充值用户不存在！");

                userAccount.ElectronicMoney += this._rechargeMoney;

                DateTime rechargeDate = DateTime.Now; // 时间要统一！
                ActUserBargain4emoney userEhistory = new ActUserBargain4emoney()
                {
                    Id = Guid.NewGuid().ToString(),
                    Userid = this._userID,
                    AwardSerialNo = "",
                    Balance = userAccount.ElectronicMoney,
                    Income = this._rechargeMoney,
                    Outlay = 0,
                    Taxation = 0,
                    TaxationSerialNo = "",
                    TradeAbstract = "充值",
                    TradeType = (int)UserTradeTypeEnum.Recharge,
                    TradeDate = rechargeDate,
                    ToUserId = this._handlerID,
                    ToUserLoginName = "客服"
                };

                /*
                var comAccount = comAccountRep.GetAll(work).FirstOrDefault();
                if (comAccount == null)
                {
                    comAccount = new ActCompanyAccountinformation()
                    {
                        Id = Guid.NewGuid().ToString(),
                        SettlementDate = rechargeDate,
                    };

                    comAccountRep.Save(comAccount, work);
                }

                comAccount.Profit += this._rechargeMoney;
                comAccount.SettlementDate = rechargeDate;
                 */

                ActCompanyRecharge userRecharge = new ActCompanyRecharge()
                {
                    Id = Guid.NewGuid().ToString(),
                    Userid = this._userID,
                    BankName = this._bankName,
                    BankCardNo = this._bankCardNo,
                    BankUserName = this._bankUserName,
                    RechargeMoney = this._rechargeMoney,
                    RechargeDate = rechargeDate,
                    BankSerialNo = this._bankSerialNo,
                    Handlerid = this._handlerID,
                    Status = this._status,
                };

                ActCompanyBargain comBargain = new ActCompanyBargain()
                {
                    Id = Guid.NewGuid().ToString(),
                    Userid = this._userID,
                    TradeType = (int)CompanyTradeTypeEnum.Recharge,
                    Income = this._rechargeMoney,
                    Outlay = 0,
                    /*
                    Balance = comAccount.Profit,
                     */
                    Balance = 0,
                    TradeDate = rechargeDate,
                    TradeAbstract = "充值",
                    AwardSerialNo = "",
                    TaxationSerialNo = "",
                };


                userAccountRep.Update(userAccount, work);
                emoneyRep.Save(userEhistory, work);
                /*
                comAccountRep.Update(comAccount, work);
                 */
                rechargeRep.Save(userRecharge, work);
                bargainRep.Save(comBargain, work);


                if (unitOfWork == null)
                    work.Commit();
            }
            catch (System.Exception ex)
            {
                throw new GfwVerifyException(ex.Message);
            }
        }

        #endregion
    }
}
